package middleware

import (
	"EinoService/utils"
	"fmt"
	"github.com/gin-gonic/gin"
	rotateLogs "github.com/lestrrat-go/file-rotatelogs"
	"github.com/rifflock/lfshook"
	"github.com/sirupsen/logrus"
	"os"
	"path"
	"strconv"
	"time"
)

// LoggerToFile 日志到文件
func LoggerToFile(config *utils.Config) gin.HandlerFunc {
	filePath := config.Logger.Path
	now := time.Now()
	filePath = path.Join(filePath, now.Format("200601"))
	if _, err := os.Stat(filePath); err != nil {
		if !os.IsNotExist(err) {
			panic(fmt.Sprintf("check path :%s stat error :%v", filePath, err))
		}
		// create directory
		err := os.MkdirAll(filePath, 0755)
		if err != nil {
			panic(fmt.Sprintf("create directory :%s error :%v", filePath, err))
		}
	}
	fileName := path.Join(filePath, "/", strconv.Itoa(now.Day())) + ".log"
	f, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		panic(fmt.Sprintf("open file %v failed: %v", fileName, err.Error()))
	}
	logger := logrus.New()
	logger.Out = f
	// 设置级别
	logLevel := config.Logger.Level
	logger.SetLevel(logrus.Level(logLevel))
	// 设置日志格式
	logger.SetFormatter(&logrus.TextFormatter{
		TimestampFormat: "2006-01-02 15:04:05",
	})
	// 分割文件规则
	logWriter, _ := rotateLogs.New(
		// 分割后的文件名称
		fileName,
		// 生成软链，指向最新的日志文件
		// rotateLogs.WithLinkName(fileName),
		// 设置最长保存时间
		rotateLogs.WithMaxAge(30*24*time.Hour),
		// 设置日志切割间隔时间
		rotateLogs.WithRotationTime(24*time.Hour),
		rotateLogs.WithRotationSize(100*1024*1024),
	)
	writeMap := lfshook.WriterMap{
		logrus.InfoLevel:  logWriter,
		logrus.FatalLevel: logWriter,
		logrus.DebugLevel: logWriter,
		logrus.WarnLevel:  logWriter,
		logrus.ErrorLevel: logWriter,
		logrus.PanicLevel: logWriter,
	}
	lfHook := lfshook.NewHook(writeMap, &logrus.JSONFormatter{
		TimestampFormat: "2006-01-02 15:04:05",
	})
	// 新增hook
	logger.AddHook(lfHook)

	return func(c *gin.Context) {
		startTime := time.Now()
		// 处理请求
		c.Next()
		endTime := time.Now()
		// 执行时间
		latencyTime := endTime.Sub(startTime)
		// 请求方式
		reqMethod := c.Request.Method
		// 请求路由
		reqUrl := c.Request.URL
		// 状态码
		statuCode := c.Writer.Status()
		// 请求IP
		clientIP := c.ClientIP()
		// 日志格式
		logger.Infof("| %3d | %13v | %15s | %s | %s",
			statuCode,
			latencyTime,
			clientIP,
			reqMethod,
			reqUrl,
		)
	}
}

// LoggerToMongo 日志记录到 MongoDB
func LoggerToMongo() gin.HandlerFunc {
	return func(c *gin.Context) {
		// todo
	}
}

// LoggerToES 日志记录到 ES
func LoggerToES() gin.HandlerFunc {
	return func(c *gin.Context) {
		// todo
	}
}

// LoggerToMQ 日志记录到 MQ
func LoggerToMQ() gin.HandlerFunc {
	return func(c *gin.Context) {
		// todo
	}
}
